import json
import threading
import time
import os
import requests
import hwapi_devs
import utils
class TTerminalHwApi:
    def __init__(self):
        self.config={
            "dataApi":"",
            "apiUrl":"https://intl.fusionsolar.huawei.com/thirdData",
            "apiUid":"江苏综集电建设有限公司",
            "apiPwd":"Zpw921061.",
            "savePath":"E:/project/zndatas/hwapi",
            "postUrl":"http://hh.hhdata.cn:31297/zn/svr/postData",
            "params": {
                "stationReal": {
                    "stationCodes": "NE=34248273",
                },
                "devReal": {
                    "devTypeId": 1,
                    "devIds": "1000000034248300,1000000034248279,1000000034248275,1000000034248298,1000000034248277,1000000034248294,1000000034248296,1000000034248292,1000000034248290,1000000034248286,1000000034248288,1000000034248306,1000000034248284,1000000034248304,1000000034248282",
                },
                "alert": {
                    "stationCodes": "NE=34248273",
                    "beginTime": 1505337987000,
                    "endTime": 1607447501000,
                    "language": "zh_CN",
                    "status": "1,2,3,4,5,6",
                    "levels": "1,2,3,4",
                    "devTypes": "1",
                    "types": "1,2,3,4,5"
                }

            },
            "timeThreshold":{
                "station": 1*60 ,
                "dev":1*60,
                "alert": 1* 60,
                "token": 25*60
            }
        }
        self.token = ""
        self.tokenTm = 0

        self.callStationTm = 30 * 60
        self.callDevTm = 5*60
        self.callAlertTm = 60

        self.stationInfo = {}
        self.alters ={}
        self.devsByIds={}
        self.devsByName={}

        self.running = False
    def init(self):
        try:
            for d in hwapi_devs.hwapi_devs:
                if d['devTypeId']==1:
                    d['values'] = {}
                    d['tags'] = [ x for x in d.keys()]
                    self.devsByIds[d['id']] = d
                    self.devsByName[d['devName']] = d
        except Exception as er:
            print(er)
    def callApi(self , apiPath , params):
        res = {
            "status":0,
            "datas":None,
            'error': None
        }
        try:
            loginFlag = self.login()
            if loginFlag:
                _url = "/".join([self.config['apiUrl'] , apiPath])
                _data = {} if params==None else params
                _headers ={
                    "Content-Type":"application/json;charset=UTF-8",
                    "XSRF-TOKEN": self.token
                }
                resp = requests.post( _url, json.dumps(_data) , headers=_headers )
                if resp.status_code ==200:
                    try:
                        resobj = json.loads(resp.text)
                        if 'failCode' in resobj.keys() and resobj['failCode']!=0:
                            failCode = resobj['failCode']
                            if failCode==305:
                                self.token = ''
                                self.tokenTm= 0
                                res = self.callApi(apiPath , params)
                            else:
                                res = {
                                    "status": -1 ,
                                    "error" : resobj
                                }
                        else:
                            res={
                                "status":1 ,
                                "datas": resobj['data']
                            }
                    except Exception as err:
                        print(err)
                else:
                    res ={
                        'status': resp.status_code ,
                        'error': resp.text
                    }
            else:
                res ={
                    'status': -3,
                    'error':"login fail."
                }
        except Exception as er:
            print(er)
        return res
    def login(self):
        res = False
        try:
            if self.tokenTm==0 or time.time() - self.tokenTm > self.config['timeThreshold']['token']:
                _url = "/".join([self.config['apiUrl'] , "login"])
                _headers={"Content-Type":"application/json;charset=UTF-8"}
                _data =json.dumps( {
                    "userName": self.config['apiUid'],
                    "systemCode": self.config['apiPwd']
                })
                resp = requests.post( _url,_data, headers=_headers )
                if resp.status_code==200:
                    if "xsrf-token" in resp.headers.keys():
                        self.token = resp.headers['xsrf-token']
                        self.tokenTm = time.time()
                        self.save('login')
                        res = True
            else:
                res = True
        except Exception as er:
            print(er)
        return res
    def callApi_StationsReal(self):
        try:
            _apiPath = "getStationRealKpi"
            _params = self.config['params']['stationReal']
            res = self.callApi(_apiPath , _params)
            if res["status"]==1 and 'datas' in res.keys() and len(res['datas'])>0:
                self.stationInfo = res['datas'][0]['dataItemMap']
                self.callStationTm = time.time()
                #print('call api station.')
                self.save('station')
        except Exception as er:
            print(er)
    def callApi_DevReal(self):
        try:
            _apiPath = "getDevRealKpi"
            _params = self.config['params']['devReal']
            res = self.callApi(_apiPath , _params)
            if res["status"]==1 and 'datas' in res.keys() and len(res['datas'])>0:
                for d in  res['datas']:
                    if d['devId'] in self.devsByIds.keys():
                        dev = self.devsByIds[d['devId']]
                        dev['value'] = d['dataItemMap']
                self.callDevTm = time.time()
                #print('call api dev.')
                self.save('dev')
        except Exception as er:
            print(er)
    def callApi_Alert(self):
        try:
            _apiPath = "getAlarmList"
            _params = self.config['params']['alert']
            self.alters = self.callApi(_apiPath , _params)
            self.callAlertTm = time.time()
            #print('call api alter.')
            if len(self.alters)>0:
                self.save('alert')
        except Exception as er:
            print(er)

    def update(self):
        try:
            tmNow = time.time()
            strD , strT = utils.TZnUtils.tm2str(tmNow)
            diffStation = tmNow - self.callStationTm
            diffDev = tmNow - self.callDevTm
            diffAlert = tmNow - self.callAlertTm
            if diffStation >= self.config['timeThreshold']['station']:
                self.callApi_StationsReal()
                self.callStationTm = tmNow
                print('call station', strD , strT)
            if diffDev >= self.config['timeThreshold']['dev']:
                self.callApi_DevReal()
                self.callDevTm = tmNow
                print('call dev', strD , strT)
            if diffAlert >= self.config['timeThreshold']['alert']:
                self.callApi_Alert()
                self.callAlertTm = tmNow
                print('call alter', strD , strT)
        except Exception as er:
            print(er)
    def start(self):
        if not self.running:
            self.running = True
            self.init()
            while self.running:
                time.sleep(2)
                self.update()
        self.running = False
    def save(self , category):
        try:
            dir = self.config['savePath']
            if os.path.exists(dir):
                strDay , strTm= utils.TZnUtils.tm2str()
                content = ""
                dir = "/".join([self.config['savePath'] , strDay])
                if not os.path.exists(dir):
                    os.makedirs(dir)
                fn = dir +"/"+ category+".join"
                if category=="login":
                    content = json.dumps({
                        "action":"login",
                        "tm": time.time(),
                        "zhtm": strDay +' ' + strTm,
                        "userName": self.config['apiUid'] ,
                        "token": self.token ,
                        "tokenTime": self.tokenTm
                    }, ensure_ascii=False)+"\n"
                elif category=="station":
                    content = json.dumps(self.stationInfo, ensure_ascii=False)+"\n"
                    vars = {}
                    for vk, vv in self.stationInfo.items():
                        vars['dp_hwStation01_'+vk] = vv
                    url = self.config['postUrl']
                    resp = requests.post(url , vars)
                    print('post datapoint.',resp)
                elif category == "dev":
                    content = json.dumps(self.devsByIds , ensure_ascii=False)+"\n"
                    vars = {}
                    for dev in self.devsByIds.values():
                        devCode = dev['id']
                        if 'value' in dev.keys() :
                            for vk, vv in dev['value'].items():
                                k = 'dp_'+str(devCode)+'_'+ vk
                                vars[k] = vv
                    url = self.config['postUrl']
                    resp = requests.post(url , vars)
                    print('post datapoint.',resp)
                elif category == "alter" and len(self.alters)>0:
                    content = json.dumps(self.alters , ensure_ascii=False)+"\n"
                if content!="":
                    with open( fn, 'a', encoding='utf8') as f:
                        f.write(content)

        except Exception as er:
            print(er)

terApi = TTerminalHwApi()
terApi.start()